package com.shijunhao.graduation.service.business.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.shijunhao.graduation.domain.dto.DiscussDto;
import com.shijunhao.graduation.domain.entity.*;
import com.shijunhao.graduation.domain.vo.CommonDiscussVo;
import com.shijunhao.graduation.domain.vo.CurrentUserVo;
import com.shijunhao.graduation.domain.vo.DiscussVo;
import com.shijunhao.graduation.enums.DictCode;
import com.shijunhao.graduation.enums.TableName;
import com.shijunhao.graduation.exception.BusinessException;
import com.shijunhao.graduation.mapper.BusinessNoteDiscussMapper;
import com.shijunhao.graduation.properties.RoleParams;
import com.shijunhao.graduation.service.business.*;
import com.shijunhao.graduation.service.scheduled.HotInfoScheduledService;
import com.shijunhao.graduation.service.system.ISystemDictService;
import com.shijunhao.graduation.service.system.impl.BaseServiceImpl;
import com.shijunhao.graduation.utils.PageUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author shijunhao
 * @since 2022-04-09
 */
@Service
public class BusinessNoteDiscussServiceImpl extends BaseServiceImpl<BusinessNoteDiscussMapper, BusinessNoteDiscuss> implements IBusinessNoteDiscussService {
    @Resource
    private IBusinessUserInfoService businessUserInfoService;
    @Resource
    private IBusinessUserGoodService goodService;
    @Resource
    private ISystemDictService systemDictService;
    @Resource
    private IBusinessNoteService businessNoteService;
    @Resource
    private HotInfoScheduledService hotInfoScheduledService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long insert(DiscussDto dto) {
        BusinessNoteDiscuss entity = new BusinessNoteDiscuss();
        BeanUtils.copyProperties(dto,entity);
        entity.setGoods(0);
        boolean b = insertOne(entity);
        if(b)
            return entity.getId();
        else
            throw new BusinessException("插入评论失败");
    }

    @Override
    public DiscussVo toVo(BusinessNoteDiscuss entity) {
        DiscussVo discussVo = new DiscussVo();
        CommonDiscussVo commonDiscussVo = new CommonDiscussVo();
        BeanUtils.copyProperties(entity,commonDiscussVo);
        //设置初始信息
        discussVo.setDiscuss(commonDiscussVo);
        //设置评论人信息
        BusinessUserInfo userInfo = businessUserInfoService.getOne(Wrappers.lambdaQuery(BusinessUserInfo.class).eq(BusinessUserInfo::getUid, entity.getCreateBy()));
        discussVo.setUserInfo(userInfo);
        //设置当前用户是否点赞信息
        SystemDictItem table = systemDictService.loadByCodeLabel(DictCode.TABLE.getCode(), TableName.BUSINESS_NOTE_DISCUSS.getLabel());
        BusinessUserGood userGood = goodService.getOneHidden(entity.getId(), table.getDictValue(), true, false);
        if(userGood != null){
            discussVo.setGood(true);
        }
        //设置子评论信息
        if(entity.getParentId() == null){
            Page<BusinessNoteDiscuss> page = page(PageUtils.initPage(), Wrappers.lambdaQuery(BusinessNoteDiscuss.class).eq(BusinessNoteDiscuss::getParentId, entity.getId()));
            Page<DiscussVo> vos = (Page<DiscussVo>) page.convert(this::toVo);
            discussVo.setChildDiscuss(vos);
        }
        return discussVo;
    }

    @Override
    public IPage<DiscussVo> page(IPage<BusinessNoteDiscuss> curPage,Long nid) {
        LambdaQueryWrapper<BusinessNoteDiscuss> wrapper = Wrappers.lambdaQuery(BusinessNoteDiscuss.class)
                .eq(BusinessNoteDiscuss::getNid, nid)
                .isNull(BusinessNoteDiscuss::getParentId);
        Page<BusinessNoteDiscuss> page = page(curPage, wrapper);
        return page.convert(this::toVo);
    }

    @Override
    public boolean delete(Long id) {
        //判断是否是管理员或该评论的文章或论坛作者是否为本人
        CurrentUserVo user = businessUserInfoService.getCurrentOrgUser();

        BusinessNoteDiscuss dis = this.getById(id);
        BusinessNote note = businessNoteService.getById(dis.getNid());
        if(!note.getCreateBy().equals(user.getUser().getId()) && !RoleParams.ADMIN.equals(user.getRole())){
            throw new BusinessException("无删除权限");
        }else{
            return super.deleteById(id);
        }
    }

    @Override
    public DiscussVo top(Long id) {
        SystemDictItem systemDictItem = systemDictService.loadByCodeLabel(DictCode.TABLE.getCode(), TableName.BUSINESS_NOTE.getLabel());
        BusinessHotInfo hotInfo = hotInfoScheduledService.getHotInfo(systemDictItem.getDictValue(), id);
        if(hotInfo.getTopDid() == null)
            return null;
        BusinessNoteDiscuss one = this.getOne(Wrappers.lambdaQuery(BusinessNoteDiscuss.class)
                .eq(BusinessNoteDiscuss::getId, hotInfo.getTopDid())
                .eq(BusinessNoteDiscuss::getNid, id)
                .isNull(BusinessNoteDiscuss::getParentId));
        return this.toVo(one);
    }

    @Override
    public boolean toTop(Long nid,Long did) {
        //判断是否是管理员或该评论的文章评论作者是否为本人
        CurrentUserVo user = businessUserInfoService.getCurrentOrgUser();
        BusinessNote note = businessNoteService.getById(nid);
        if(!note.getCreateBy().equals(user.getUser().getId()) && !RoleParams.ADMIN.equals(user.getRole())){
            throw new BusinessException("无删除操作他人文章");
        }else{
            SystemDictItem systemDictItem = systemDictService.loadByCodeLabel(DictCode.TABLE.getCode(), TableName.BUSINESS_NOTE.getLabel());
            BusinessHotInfo hotInfo = hotInfoScheduledService.getHotInfo(systemDictItem.getDictValue(), nid);
            if(did.equals(hotInfo.getTopDid())){
                hotInfoScheduledService.updateHotInfo(hotInfo1 -> hotInfo1.setTopDid(null),systemDictItem.getDictValue(), nid);
                return false;
            }else{
                hotInfoScheduledService.updateHotInfo(hotInfo1 -> hotInfo1.setTopDid(did),systemDictItem.getDictValue(), nid);
                return true;
            }

        }
    }
}
